package com.example.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.auth.domain.DataNode;
import com.example.auth.domain.User;
import com.example.auth.domain.UserIdcard;
import com.example.auth.domain.UserPhone;
import com.example.auth.domain.vo.UserVo;
import com.example.auth.service.DataNodeService;
import com.example.auth.service.UserIdcardService;
import com.example.auth.service.UserPhoneService;
import com.example.auth.service.UserService;
import com.example.config.ResultUtil;
import com.example.config.exception.GlobalExcetion;
import com.example.util.*;
import org.apache.catalina.security.SecurityUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private DataNodeService dataNodeService;

    @Autowired
    private UserPhoneService userPhoneService;

    @Autowired
    private UserIdcardService userIdcardService;


    @GetMapping("/page")
    public JSONObject getIPage(@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                                @RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize,
                                @RequestParam(value = "userName",required = false)String userName){
        IPage<User> iPage=userService.pageList(new Page(pageNum,pageSize),userName);
        JSONObject result=new JSONObject();
        JSONArray array=new JSONArray();
        result.put("data",array);
        result.put("total",iPage.getTotal());
        if(iPage.getRecords()!=null && iPage.getRecords().size()>0){
            for(User user:iPage.getRecords()){
                JSONObject obj=new JSONObject();
                List<String> nodeIds=StringSplitUtil.splitToList(user.getNodeId());
                List<DataNode> dataNodeList=dataNodeService.getByIds(nodeIds);
                obj.putAll(JSONObject.parseObject(JSONObject.toJSONString(user, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteMapNullValue)));
                String nodeName=dataNodeList.stream().map((e)->e.getNodeName()).collect(Collectors.joining(","));
                String serverName=dataNodeList.stream().map((e)->e.getNodeServerName()).collect(Collectors.joining(","));
                String serverNo=dataNodeList.stream().map((e)->e.getNodeNo()).collect(Collectors.joining(","));
                obj.put("nodeName",nodeName);
                obj.put("serverName",serverName);
                obj.put("serverNo",serverNo);
                array.add(obj);
            }
        }
        return ResultUtil.successInfo(result);
    }


    @GetMapping("/search")
    public User searchUserApi(@RequestParam("username") String username) throws GlobalExcetion {
        User user=userService.findByUsername(username);
        valitedUser(user);
        return user;
    }

    @GetMapping("/search/hash")
    public User searchUserHashApi(@RequestParam("username") String username) throws GlobalExcetion {
        User user=userService.getUserByHashUserName(username);
        valitedUser(user);
        return user;
    }

    private void valitedUser(User user) throws GlobalExcetion {
        if(user!=null ){
            if(user.getPhone()==null || "".equals(user.getPhone())){
                boolean isPhone=true;
                while (isPhone){
                    String phone= ChineseMobileNumberGenerator.generate();
                    UserPhone userPhone=userPhoneService.getUserPhoneByPhone(phone);
                    if(userPhone==null){
                        isPhone=false;
                        user.setPhone(phone);
                        userService.updateUserById(user);
                        UserPhone p=new UserPhone();
                        p.setUserId(user.getUuid());
                        p.setUserPhone(phone);
                        p.setUserName(user.getUsername());
                        userPhoneService.saveUserPhone(p);
                    }
                }
            }
            if(user.getIdCard()==null || "".equals(user.getIdCard())){
                boolean isIdCard=true;
                while (isIdCard){
                    String idCard=IDCardGenerator.generate();
                    UserIdcard userIdcard=userIdcardService.getByIdCard(idCard);
                    if(userIdcard==null){
                        isIdCard=false;
                        UserIdcard idcard=new UserIdcard();
                        idcard.setUserId(user.getUuid());
                        idcard.setUserIdcard(idCard);
                        idcard.setUserName(user.getUsername());
                        userIdcardService.saveUserIdcard(idcard);
                        user.setIdCard(idCard);
                        userService.updateUserById(user);
                    }
                }
            }
        }
    }

    @GetMapping("/total/hash")
    public Integer getUserHashTotal() throws ExecutionException, InterruptedException {
        Integer total=userService.findUserHashTotalNum();
        return total;
    }

    @GetMapping("/search/userId")
    public User searchUserByUserIdApi(@RequestParam("userId") String userId) throws GlobalExcetion {
        User user=userService.getUserByHashUserId(userId);
        valitedUser(user);
        return user;
    }

    @GetMapping("/search/userId/hash")
    public User searchUserByUserIdHashApi(@RequestParam("userId") String userId) throws GlobalExcetion {
        User user=userService.getUserByHashUserId(userId);
        valitedUser(user);
        return user;
    }

    @PostMapping("/registerUser")
    public JSONObject registerUser(@RequestBody @Validated UserVo vo) throws GlobalExcetion {
        User user=new User();
        BeanUtils.copyProperties(vo,user);
        userService.registerUser(user);
        valitedUser(user);
        return ResultUtil.successInfo("操作成功");
    }


    @PostMapping("/registerUserHash")
    public JSONObject registerUserHash(@RequestBody @Validated UserVo vo) throws GlobalExcetion {
        User user=new User();
        BeanUtils.copyProperties(vo,user);
        userService.registerUserByHashShard(user);
        valitedUser(user);
        return ResultUtil.successInfo("操作成功");
    }

    @GetMapping("/dataNodeByUserName")
    public DataNode findNodeByUsername(@RequestParam("username") String username){
        return userService.findDataNodeByUserName(username);
    }

    @GetMapping("/dataNodeByUserId")
    public DataNode findNodeByUserId(@RequestParam("userId") String userId){
        return userService.findDataNodeByUserId(userId);
    }

    @PostMapping("/updatepwd")
    public JSONObject updatePassword(@RequestBody @Validated UserVo vo){
        userService.updatePwd(vo.getUsername(), vo.getPassword());
        return Results.success("密码修改成功");
    }

    @GetMapping("/delete/userId")
    public JSONObject deleteUserById(@RequestParam("userId") String userId){
        userService.deleteUserByUserId(userId);
        return Results.success("删除成功");
    }

    @GetMapping("/getusernode")
    public DataNode getUserNodeServer(@RequestParam("userName")String userName,
                                        @RequestParam("nodeNo")String nodeNo) throws GlobalExcetion {
        DataNode dataNode= userService.findDataNodeByUserName(userName,nodeNo);
        return dataNode;
    }

    @GetMapping("/getusernode/userId")
    public DataNode getUserNodeServerUserId(@RequestParam("userId")String userId,
                                      @RequestParam("nodeNo")String nodeNo) throws GlobalExcetion {
        DataNode dataNode= userService.findDataNodeByUserId(userId,nodeNo);
        return dataNode;
    }

    @GetMapping("/getusernodes")
    public JSONObject getUserNodes(@RequestParam("userName")String userName){
        User user=userService.getUserByHashUserName(userName);
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("user",user);
        List<String> ids= StringSplitUtil.splitToList(user.getNodeId());
        List<DataNode> dataNodeList=dataNodeService.listByIds(ids);
        jsonObject.put("dataNodeList",dataNodeList);
        return ResultUtil.successInfo(jsonObject);
    }

    @PostMapping("updateIDcard")
    public JSONObject updateIDcard(@RequestParam("uid")String uid,
                                   @RequestParam("iDCard")String idCard) throws GlobalExcetion {
        boolean isPhone= IDCardValidator.isValid(idCard);
        if(!isPhone){
            throw new GlobalExcetion(1,"身份证号码不正确");
        }
        User user=userService.getUserByHashUserId(uid);
        if(user==null){
            throw new GlobalExcetion(1,"用户数据不存在");
        }
        UserIdcard userIdcard=userIdcardService.getByIdCard(idCard);
        if(userIdcard==null){
            userIdcard=new UserIdcard();
            userIdcard.setUserId(uid);
            userIdcard.setUserName(user.getUsername());
            userIdcard.setUserIdcard(idCard);
            userIdcardService.saveUserIdcard(userIdcard);
        }else {
            userIdcard.setUserIdcard(idCard);
            userIdcard.setUserId(uid);
            userIdcard.setUserName(user.getUsername());
            userIdcardService.saveUserIdcard(userIdcard);
        }
        return Results.success("修改成功");
    }

    @PostMapping("updatePhone")
    public JSONObject updatePhone(@RequestParam("uid")String uid,
                                  @RequestParam("phone")String phone) throws GlobalExcetion {
        boolean isPhone=PhoneValidator.isValidPhone(phone);
        if(!isPhone){
            throw new GlobalExcetion(1,"手机号码不正确");
        }
        User user=userService.getUserByHashUserId(uid);
        if(user==null){
            throw new GlobalExcetion(1,"用户数据不存在");
        }
        UserPhone userPhone=userPhoneService.getUserPhoneByPhone(phone);
        if(userPhone==null){
            UserPhone phoneUser=new UserPhone();
            phoneUser.setUserId(uid);
            phoneUser.setUserPhone(phone);
            phoneUser.setUserName(user.getUsername());
            userPhoneService.saveUserPhone(phoneUser);
        }else {
            userPhone.setUserName(user.getUsername());
            userPhone.setUserId(uid);
            userPhoneService.updateUserPhoneById(userPhone);
        }
        return Results.success("手机号修改成功");
    }
}
